package com.tansun.easycare.rule.table.singletblindex.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.tansun.easycare.rule.codeblock.service.RuleCodeblockService;
import com.tansun.easycare.rule.common.model.RuleSetParamInfo;
import com.tansun.easycare.rule.common.rulebasebean.Action;
import com.tansun.easycare.rule.common.rulebasebean.DThen;
import com.tansun.easycare.rule.common.rulebasebean.DWhen;
import com.tansun.easycare.rule.common.rulebasebean.Fact;
import com.tansun.easycare.rule.common.rulebasebean.RuleCollection;
import com.tansun.easycare.rule.common.rulebasebean.RuleItem;
import com.tansun.easycare.rule.common.service.DataBomService;
import com.tansun.easycare.rule.common.service.impl.RuleBaseServiceImpl;
import com.tansun.easycare.rule.datamodel.entity.RuleDataparams;
import com.tansun.easycare.rule.datamodel.service.RuleDataparamsService;
import com.tansun.easycare.rule.exception.BizException;
import com.tansun.easycare.rule.referencedata.entity.RuleReferenceData;
import com.tansun.easycare.rule.referencedata.service.RuleReferenceDataService;
import com.tansun.easycare.rule.rulemange.entity.RuleManage;
import com.tansun.easycare.rule.rulemange.service.RuleManageService;
import com.tansun.easycare.rule.ruleversion.entity.RuleVersioninfo;
import com.tansun.easycare.rule.ruleversion.service.RuleVersioninfoService;
import com.tansun.easycare.rule.table.dao.RuleDecisiontableDetailDao;
import com.tansun.easycare.rule.table.entity.RuleDecisiontableDetail;
import com.tansun.easycare.rule.table.singletblindex.model.SingleTblIndexEntity;
import com.tansun.easycare.rule.table.singletblindex.model.SingleTblIndexItem;
import com.tansun.easycare.rule.table.singletblindex.model.SingleTblIndexRow;
import com.tansun.easycare.rule.table.singletblindex.service.SingleTblIndexService;
import com.tansun.easycare.rule.utils.DroolsUtils;
import com.tansun.rule.api.IRuleService;
import com.tansun.rule.common.RuleModelTypeEnum;
import com.tansun.rule.model.toolbean.BooleanFact;
import com.tansun.rule.model.toolbean.FormulaFact;
import com.tansun.rule.model.toolbean.FunctionItem;
import com.tansun.rule.model.toolbean.NumericFact;
import com.tansun.rule.model.toolbean.RuleModel;
import com.tansun.rule.model.toolbean.RuleModel.RuleType;
import com.tansun.rule.model.toolbean.RuleResult;
import com.tansun.rule.model.toolbean.StringFact;
import com.tansun.rule.utils.LoggerManager;

@Service("singleTblIndexService")
public class SingleTblIndexServiceImpl extends RuleBaseServiceImpl<RuleDecisiontableDetailDao, RuleDecisiontableDetail> implements SingleTblIndexService {

    @Autowired
    private RuleReferenceDataService ruleReferenceDataService;
    @Autowired
    private RuleManageService ruleManageService;
    @Autowired
    private IRuleService ruleService;
    @Autowired
    private RuleVersioninfoService ruleVersioninfoService;
	@Autowired
	private  DataBomService dataBomService;
	@Autowired
	private  RuleDataparamsService  ruleDataparamsService;
    @Autowired
    private RuleCodeblockService ruleCodeblockService;
    

	
    @Override
    public void saveOrUpdate(SingleTblIndexEntity indexEntity) throws BizException {
        try {
            RuleManage ruleManage = indexEntity.getIndexModel();
            ruleManage.setStatus("1");
            ruleManage.setModelType(RuleModelTypeEnum.SingleTblIndex.getCode());
            ruleManage = ruleManageService.saveOrUpdate(ruleManage);
            List<SingleTblIndexRow> indexList = indexEntity.getSingleTblIndexList();
            /**函数模式*/
//            String context = generateRule(ruleManage, indexList);
            String context = generateRuleFuncMode(ruleManage, indexList);
            if (context == null) 
            	throw new BizException("未生成规则");
            RuleDecisiontableDetail decisiontableDetail = null;
            int col = 0;//列
            int row = 0;//行
            List<SingleTblIndexItem> itList = null;
            List<RuleDecisiontableDetail> rList = new ArrayList<RuleDecisiontableDetail>();
            Map<String, RuleReferenceData> dataMap = new HashMap<String, RuleReferenceData>();
            //收集函数变量
            List<RuleDataparams> funcparamList = new ArrayList<RuleDataparams>();
            for (SingleTblIndexRow indexRow : indexList) {
                itList = indexRow.getSingleTblRow();
                for (SingleTblIndexItem indexItem : itList) {
                	if("1".equals(indexItem.getIsfuncparam())) {
                		//收集函数变量
						RuleDataparams ruleDataparams = new RuleDataparams();
						ruleDataparams.setClassName(indexItem.getClassName());
						ruleDataparams.setName(indexItem.getNameEN());
						funcparamList.add(ruleDataparams);
                	}
                    decisiontableDetail = new RuleDecisiontableDetail();
                    BeanUtils.copyProperties(decisiontableDetail, indexItem);
                    decisiontableDetail.setColumnNo(col);
                    decisiontableDetail.setRowNo(row);
                    decisiontableDetail.setModelType(ruleManage.getModelType());
                    decisiontableDetail.setNamecn(indexItem.getNameCN());
                    decisiontableDetail.setNameen(indexItem.getNameEN());
                    decisiontableDetail.setVersion(ruleManage.getVersion());
                    decisiontableDetail.setManageId(ruleManage.getId());
                    decisiontableDetail.setProjectCode(ruleManage.getProjectCode());
                    decisiontableDetail.setPattern(indexItem.getPattern());
                    decisiontableDetail.setCollection(indexItem.getCollection());
                    decisiontableDetail.setIsfuncparam(indexItem.getIsfuncparam());
                    rList.add(decisiontableDetail);
                    this.ruleReferenceDataService.collectTableDetail(decisiontableDetail, dataMap, ruleManage);
                    col++;
                }
                col = 0;
                row++;
            }
            this.insertBatch(rList);
            this.ruleReferenceDataService.saveReferenceDataFuncRef(funcparamList,ruleManage);
            this.ruleReferenceDataService.saveReferenceData(dataMap);
            //保存规则信息
            RuleVersioninfo ruleVersioninfo = new RuleVersioninfo();
            ruleVersioninfo.init(ruleManage, context);
            ruleVersioninfo.setDatasetNames(indexEntity.getDatasetNames());
            ruleVersioninfoService.save(ruleVersioninfo);
        } catch (Exception e) {
        	LoggerManager.error(e.getMessage(), e, this.getClass());
            throw new BizException( "E-000500",e.getMessage());
        }
    }
    /**
     * 显示java代码
     */
	@Override
	public String showJavaCode(SingleTblIndexEntity indexEntity) throws BizException {
		return null;
/*		RuleManage ruleManage = indexEntity.getIndexModel();
		ruleManage = ruleManageService.get(ruleManage.getId());
        List<SingleTblIndexRow> indexList = indexEntity.getSingleTblIndexList();
        funcParamMap = ruleDataparamsService.getdataparams(ruleManage.getProjectCode());
        List<SingleTblIndexRowSC> newIndexList = ClassChangeUtils.changeClassList(indexList);
        RuleManageSC ruleManageSC = ClassChangeUtils.<RuleManage,RuleManageSC>changeClass(ruleManage);
        return SingleTblIndexCreate.createCode(ruleManageSC, newIndexList, funcParamMap);*/
		
	}
	
    private String generateRule(RuleManage index, List<SingleTblIndexRow> indexItemList){
    	funcParamMap = ruleDataparamsService.getdataparams(index.getProjectCode());
    	
    	RuleModel ruleModel = new RuleModel();
    	ruleModel.setModelName(index.getName());
    	ruleModel.setModelCode(index.getCode());
//    	ruleModel.setModelVersion(index.getVersion());
    	ruleModel.setRuleType(RuleType.ruleIndex);
    	
    	int priority = 1;
        for (SingleTblIndexRow row : indexItemList) {
            List<SingleTblIndexItem> rowList = row.getSingleTblRow();
            
            String randomIdString = com.tansun.rule.utils.StringUtils.GenerateRandom(6);
            String ruleName = "singleIndex_" + randomIdString;
            com.tansun.rule.model.toolbean.RuleItem rule = new com.tansun.rule.model.toolbean.RuleItem();
            rule.setRuleName(ruleName);
            for (SingleTblIndexItem item : rowList) {
                item.setTabId(randomIdString);
                if (StringUtils.isEmpty(item.getControlValue()))
                    continue;
                if ("in".equals(item.getContentType())) {
                    //whenStr += generateDrl(item, "when") + ",";
                	com.tansun.rule.model.toolbean.Fact fact = generateFact(item, "when");
                	rule.getdWhen().getFactList().add(fact);
                } else {
                    //thenStr += generateDrl(item, "then");
                	com.tansun.rule.model.toolbean.Fact fact = generateFact(item, "then");
                	rule.setRuleResultInfo(item.getControlValue());
                	rule.getdThen().getListAction().add(fact);
                }
            }
            rule.setSalience(priority--);
            rule.setActivationGroup(index.getCode());
            ruleModel.getListItem().add(rule);
        }
    	RuleResult result = ruleService.generateRule(ruleModel);
    	if (RuleResult.FAILURE.equals(result.getRetCode())) {
            throw new RuntimeException(result.getRetMsg());
        } else {
            return result.getRetContent();
        }
    }

    private String generateRuleFuncMode(RuleManage index, List<SingleTblIndexRow> indexItemList){
    	funcParamMap = ruleDataparamsService.getdataparams(index.getProjectCode());
    	String id = com.tansun.rule.utils.StringUtils.GenerateRandom(6);
    	String ruleName = "singleIndex_" + id ;
    	String functionName = "singleIndex_func_"+id;
    	
    	com.tansun.rule.model.toolbean.Fact fact = new com.tansun.rule.model.toolbean.Fact();
    	fact.setContent("	"+functionName+"($insertMap,metaMap,ruleHelper,droolsRuleLog,drools);\r\n");
    	
        com.tansun.rule.model.toolbean.RuleItem rule = new com.tansun.rule.model.toolbean.RuleItem();
    	rule.getdThen().getListAction().add(fact);
        rule.setRuleName(ruleName);
        rule.setSalience(1);
        rule.setActivationGroup(index.getCode());
        rule.setAddLog(false);
    	RuleModel ruleModel = new RuleModel();
    	ruleModel.getDroolsImport().add("org.drools.core.spi.KnowledgeHelper");
    	ruleModel.setModelName(index.getName());
    	ruleModel.setModelCode(index.getCode());
    	ruleModel.setRuleType(RuleType.ruleIndex);
    	ruleModel.getListItem().add(rule);
    	ruleModel.setFuncDrl(this.ruleCodeblockService.getEffectiveFunc(index.getProjectCode()));
    	StringBuilder code = new StringBuilder();
        for (int i=0;i<indexItemList.size();i++) {
        	SingleTblIndexRow row = indexItemList.get(i);
            List<SingleTblIndexItem> rowList = row.getSingleTblRow();

            List<String> ifcondition = new ArrayList<String>();
            List<String> actions = new ArrayList<String>();
            for (SingleTblIndexItem item : rowList) {
            	
                if (StringUtils.isEmpty(item.getControlValue()))
                    continue;
                if (StringUtils.isEmpty(item.getNameEN()))
                	continue;
                if (StringUtils.isEmpty(item.getTabId())) {
                	item.setTabId(com.tansun.rule.utils.StringUtils.GenerateRandom(6));
                }
                if ("in".equals(item.getContentType())) {
                	if (StringUtils.isEmpty(item.getDomain()) || item.getControlValue().indexOf("[") < 0) {
                        String s=item.getControlValue().substring(0,1);
                        if("(".equals(s) || "[".equals(s)){
                            item.setLowerOpt(s);
                            item.setControlValue(item.getControlValue().substring(item.getControlValue().indexOf(s)+1));
                        }
                        String ss=item.getControlValue().substring(item.getControlValue().length()-1);
                        if(")".equals(ss) || "]".equals(ss)){
                            item.setUpperOpt(ss);
                            item.setControlValue(item.getControlValue().substring(0,item.getControlValue().lastIndexOf(ss)));
                        }
                	}
                	String cond = generateCode(item, "when");
                	if(StringUtils.isNotEmpty(cond)) {
                		ifcondition.add(cond);
                	}
                } else {
                	String action = generateCode(item, "then");
                	if(StringUtils.isNotEmpty(action)) {
                		actions.add(action);
                		actions.add("droolsRuleLog.addLogs(\""+index.getCode()+"\",\"ruleIndex\",\""+index.getName()+"\", drools,\""+item.getControlValue()+"\");");
                		actions.add("droolsRuleLog.addTracks(\""+item.getTabId()+"\");");
                	}
                }
            }
            if(i==0) {
            	code.append("if( ("+StringUtils.join(ifcondition,") && (")+") ){\r\n");
            	code.append("		"+StringUtils.join(actions,"\r\n		")+"\r\n");
            	code.append("		return;\r\n");
            	code.append("	}");
            }else if((i==indexItemList.size()-1)&&indexItemList.size()>1 && ifcondition.size() == 0) {
            	code.append("else {\r\n");
            	code.append("		"+StringUtils.join(actions,"\r\n		")+"\r\n");
            	code.append("		return;\r\n");
            	code.append("	}");
            }else {
            	code.append("else if( ("+StringUtils.join(ifcondition,") && (")+") ){\r\n");
            	code.append("		"+StringUtils.join(actions,"\r\n		")+"\r\n");
            	code.append("		return;\r\n");
            	code.append("	}");
            }
        }
        FunctionItem functionItem = new FunctionItem(); 
        functionItem.setFunctionBody(code.toString());
        functionItem.setReturnType("void");
        functionItem.setFunctionName(functionName);
        functionItem.setParams(new ArrayList<String[]>());
        functionItem.getParams().add(new String[] {"Map","dataMap"});
        functionItem.getParams().add(new String[] {"Map","metaMap"});
        functionItem.getParams().add(new String[] {"RuleHelper","ruleHelper"});
        functionItem.getParams().add(new String[] {"DroolsRuleLog","droolsRuleLog"});
        functionItem.getParams().add(new String[] {"KnowledgeHelper","drools"});
        ruleModel.getFuncList().add(functionItem);
        
    	RuleResult result = ruleService.generateRule(ruleModel);
    	if (RuleResult.FAILURE.equals(result.getRetCode())) {
            throw new RuntimeException(result.getRetMsg());
        } else {
            return result.getRetContent();
        }
    }
    
    private String writeDrl(RuleManage index, List<SingleTblIndexRow> indexItemList) throws Exception {
        if (indexItemList == null || indexItemList.size() == 0)
            return null;
        RuleCollection ruleCollection = new RuleCollection();
        ruleCollection.setDrlName(index.getCode());
        ruleCollection.setObjName(index.getName());
        ruleCollection.setContentType(RuleCollection.RULEINDEX);
        ruleCollection.setVersion(index.getVersion());
        //生成动作组 从1开始递减
        int priority = 1;
        for (SingleTblIndexRow row : indexItemList) {
            List<SingleTblIndexItem> rowList = row.getSingleTblRow();
            String whenStr = "";
            String thenStr = "";
            String randomIdString = com.tansun.rule.utils.StringUtils.GenerateRandom(6);
            String ruleName = "singleIndex_" + randomIdString;
            for (SingleTblIndexItem item : rowList) {
                item.setTabId(randomIdString);
                if (StringUtils.isEmpty(item.getControlValue()))
                    continue;
                if ("in".equals(item.getContentType())) {
                    whenStr += generateDrl(item, "when") + ",";
                } else {
                    thenStr += generateDrl(item, "then");
                }
            }
            whenStr = whenStr.substring(0, whenStr.length() - 1);
            RuleItem ruleItem = getCustomRule(ruleName, priority, whenStr, thenStr);
            ruleCollection.getListItem().add(ruleItem);
            priority--;
        }
        //写入DRL文件

        return DroolsUtils.convert2Drl(ruleCollection);
    }

    private String generateDrl(SingleTblIndexItem item, String type) {
        String retStr = "";
        String vals = item.getControlValue();
        String dataType = item.getDataType();
        if (type.equals("when")) {
            retStr = "this[\"" + item.getClassName() + "\"][\"" + item.getNameEN() + "\"]";
            if (!StringUtils.isEmpty(item.getPosition())) {
                retStr += ".get(" + item.getPosition() + ")";
            }
            if (item.getDataType().equals("String")) {
                if (!StringUtils.isEmpty(item.getDomain()) && item.getControlValue().indexOf("[") >= 0) {
                    vals = item.getControlValue().substring(1, item.getControlValue().length() - 1);
                    retStr += " in (" + vals + ") ";
                } else {

                    retStr += " == " + "\"" + item.getControlValue() + "\"";
                }
            } else if (item.getDataType().equals("Boolean")) {
                retStr = retStr + "==" + (item.getControlValue().equals("1") ? "true" : "false");
            } else {
                String lowerOpt = item.getLowerOpt();
                String upperOpt = item.getUpperOpt();

                if (vals.indexOf(",") < 0) return "";
                String[] valArr = vals.split(",");
                if (dataType.equals("Date")) {
                    for (int i = 0; i < valArr.length; i++) {
                        valArr[i] = "\"" + valArr[i] + "\"";
                    }
                }
                String expression = retStr;
                if (!StringUtils.isEmpty(lowerOpt) && valArr[0].length() > 0&&!valArr[0].equals("undefined")) {
                	
                    if (lowerOpt.equals("[")) {
                        retStr = expression + ">=" + valArr[0];
                    } else {
                        retStr = expression + ">" + valArr[0];
                    }
                } else {
                    retStr = "";
                }
                if (valArr.length == 2&&!valArr[1].equals("undefined")) {
                    if (!StringUtils.isEmpty(retStr))
                        retStr += " && ";
                    if (upperOpt.equals("]")) {
                        retStr += expression + "<=" + valArr[1];
                    } else {
                        retStr += expression + "<" + valArr[1];
                    }
                }
//				if(vals.indexOf(",")<0)
//					return "";
//				String[] valArr = item.getControlValue().split(",");
//				String expression = retStr;
//				if(item.getLowerOpt().equals("[")){
//					retStr = expression + ">="+valArr[0];
//				}else{
//					retStr = expression + ">"+valArr[0];
//				}
//				if(valArr.length==2){
//					retStr += " && ";
//					if(item.getUpperOpt().equals("]")){
//						retStr += expression+"<="+valArr[1];
//					}else{
//						retStr += expression+"<"+valArr[1];
//					}
//				}
            }
        } else if (type.equals("then")) {
            retStr = "ruleHelper.setValue";
            if ("List".equals(item.getCollection())) {
                retStr = "ruleHelper.insertValue";
            }
            retStr += "($insertMap,\"" + item.getClassName() + "." + item.getNameEN() + "\",\"" + item.getControlValue() + "\");\n";
        }
        return retStr;
    }
    
    private String generateCode(SingleTblIndexItem item, String type) {
    	String name = item.getClassName()+"."+item.getNameEN();
    	String funcName = funcParamMap.get(name);
    	String vals = item.getControlValue();
    	String dataType  = item.getDataType();
    	if (type.equals("when")) {
    		if(item.getControlValue().equals("其他")) {
    			return "";
    		}else {
	    		if (dataType.equals("String")) {
	    			if (!StringUtils.isEmpty(item.getDomain()) && item.getControlValue().indexOf("[") >= 0) {
	    				vals = item.getControlValue().substring(1, item.getControlValue().length() - 1);
	    				return getStringCode(name,funcName,vals.replaceAll("\"", "").split(","),true,item);
	    			} else {
	    			    //决策表string类型新增!= 20200101 ljt
                        String lowerOpt = "==";
                        if(StringUtils.isNotBlank(item.getLowerOpt())){//excle默认 ==
                            lowerOpt = item.getLowerOpt();
                        }
                        return getStringCode(name,funcName,lowerOpt, item.getControlValue(),item);
	    			}
	    		} else if (dataType.equals("Boolean")) {
	    			if(item.getControlValue().equals("1") || item.getControlValue().equals("true")) {
	    				return getBooleanCode(name,funcName, "==", "true" , item);
	    			}else {
	    				return getBooleanCode(name,funcName, "==", "false", item);
	    			}
	    		} else {
	    			String lowerOpt = item.getLowerOpt();
	    			if("[".equals(lowerOpt)) lowerOpt = ">=";
	    			if("(".equals(lowerOpt)) lowerOpt = ">";
	    			String upperOpt = "]".equals(item.getUpperOpt())? "<=":"<";
	    			String[] valArr = vals.split(",");
	    			if (valArr.length==0){
	    				return "";
	    			}
	    			if("Date".equals(dataType)) {
        				String dateStr1=valArr.length>1?'"'+valArr[1]+'"':null;
        				String dateStr2=valArr[0].length()>0?'"'+valArr[0]+'"':null;
        				return getNumericCode(name,funcName,dataType,dateStr1, upperOpt, dateStr2, lowerOpt, item);
        			}else {
        				return getNumericCode(name,funcName,dataType, valArr.length>1?valArr[1]:null, upperOpt, valArr[0], lowerOpt, item);
        			}
	    			
	    		}
    		}
    	} else{
    		String val = item.getControlValue();
    		if("true".equals(item.getIsDerives())){
    			val = "MathHelper.invokeMath(dataMap,metaMap,\"" + val + "\")";
    			return getNumericCode(name, val, item);
    		}else{
    			return getStringCode(name, val, item);
    		}
    	}
    }
    private String getNumericCode(String name, String optValue,SingleTblIndexItem item) {
    	StringBuilder to = new StringBuilder();
		if("List".equals(item.getCollection())) {
			to.append("ruleHelper.insertValue(dataMap,\"");
			to.append(name).append("\",").append(optValue).append(");");
		}else {
			to.append("ruleHelper.setValue(dataMap,\"").append(name).append("\",")
			.append(optValue).append(");");
		}
		return to.toString();
    }
    private String getNumericCode(String name, String funcName, String datatype,String upperLimit, String upperSymbol, String lowerLimit, String lowerSymbol,SingleTblIndexItem item) {
    	String symbol = null;
    	String optValue = null;
		if (upperLimit != null && !"".equals(upperLimit)) {
			if (lowerLimit == null || "".equals(lowerLimit)) {
				symbol = upperSymbol;
				optValue = upperLimit;
			}
		} else {
			symbol = lowerSymbol;
			optValue = lowerLimit;
		}
		if("BigInteger".equalsIgnoreCase(datatype)) {
			datatype = "Long";
		}else if("BigDecimal".equalsIgnoreCase(datatype)) {
			datatype = "Double";
		}
		StringBuilder to = new StringBuilder();
		if (symbol != null) {
			if (StringUtils.isEmpty(funcName)) {
				String param = "";
				if("List".equals(item.getCollection())) {
					param = "(("+datatype+")((List)ruleHelper.getValue(dataMap,\""+name+"\")).get("+item.getPosition()+"))";
				}else {
					param = "(("+datatype+")ruleHelper.getValue(dataMap,\""+name+"\"))";
				}
				if(datatype.equals("Date")) {
					to.append(param).append(".compareTo(").append(optValue).append(") ").append(symbol).append(" 0");
				}else {
					to.append(param).append(" ").append(symbol).append(" ").append(optValue);
				}
			} else {
				to.append(funcName).append(symbol).append(" ").append(optValue);
			}
		} else if (StringUtils.isEmpty(funcName)) {
			String param = "";
			datatype = datatype.equals("Date")?"String":datatype;
			if("List".equals(item.getCollection())) {
				param = "(("+datatype+")((List)ruleHelper.getValue(dataMap,\""+name+"\")).get("+item.getPosition()+"))";
			}else {
				param = "(("+datatype+")ruleHelper.getValue(dataMap,\""+name+"\"))";
			}
			if(datatype.equals("String")) {
				to.append(param).append(".compareTo(").append(upperLimit).append(") ").append(upperSymbol).append(" 0").append(" && ")
				.append(param).append(".compareTo(").append(lowerLimit).append(") ").append(lowerSymbol).append(" 0");
			}else {
				to.append(param).append(" ").append(upperSymbol).append(" ").append(upperLimit).append(" && ")
				.append(param).append(" ").append(lowerSymbol).append(" ").append(lowerLimit);
			}
		} else {
			to.append(funcName).append(upperSymbol).append(" ").append(upperLimit).append(" && ")
					.append(funcName).append(lowerSymbol).append(" ").append(lowerLimit);
		}

		return to.toString();
    }
    private String getBooleanCode(String name, String funcName, String symbol, String optValue, SingleTblIndexItem item) {
    	StringBuilder to = new StringBuilder();
		if (StringUtils.isEmpty(funcName)) {
			String param = "";
			if("List".equals(item.getCollection())) {
				param = "((Boolean)((List)ruleHelper.getValue(dataMap,\""+name+"\")).get("+item.getPosition()+"))";
			}else {
				param = "((Boolean)ruleHelper.getValue(dataMap,\""+name+"\"))";
			}
			to.append(param).append(symbol).append(optValue);
		} else {
			to.append(funcName).append(symbol).append(optValue);
		}
		return to.toString();
    }
    private String getStringCode(String name, String optValue,SingleTblIndexItem item) {
		StringBuilder to = new StringBuilder();
		if("List".equals(item.getCollection())) {
			to.append("ruleHelper.insertValue(dataMap,\"");
			to.append(name).append("\",").append("\"").append(optValue).append("\");");
		}else {
			to.append("ruleHelper.setValue(dataMap,\"");
			to.append(name).append("\",").append("\"").append(optValue).append("\");");
		}
		return to.toString();
    }
    private String getStringCode(String name, String funcName, String symbol, String optValue,SingleTblIndexItem item) {
    	StringBuilder to = new StringBuilder();
    	to.append("\"").append(optValue).append("\".equals(");
		if (StringUtils.isEmpty(funcName)) {
			if("List".equals(item.getCollection())) {
				to.append("((String)((List)ruleHelper.getValue(dataMap,\"").append(name).append("\")).get(").append(item.getPosition()).append("))");
			}else {
				to.append("((String)ruleHelper.getValue(dataMap,\"").append(name).append("\"))");
			}
		} else {
			to.append("((String)"+funcName+")");
		}
		to.append(")");
		if("!=".equals(symbol)) {
			return "!"+to.toString();
		}else {
			return to.toString();	
		}
    }
    private String getStringCode(String name,String funcName,String[] optValues,boolean  isIn, SingleTblIndexItem item) {
		StringBuilder to = new StringBuilder();
		to = new StringBuilder();
		
		if(optValues.length>1) {
			to.append("Arrays.asList(\"").append(StringUtils.join(optValues,"\",\"")).append("\").contains(");
		}else if(optValues.length==1) {
			to.append("\"").append(optValues[0]).append("\".equals(");
		}else {
			to.append("\"\".equals(");
		}
		
		if (StringUtils.isEmpty(funcName)) {
			if("List".equals(item.getCollection())) {
				to.append("(String)((List)ruleHelper.getValue(dataMap,\"").append(name).append("\")).get(").append(item.getPosition()).append("))");
			}else {
				to.append("(String)ruleHelper.getValue(dataMap,\"").append(name).append("\"))");
			}
		} else {
			to.append("(String)"+funcName+")");
		}

		return to.toString();
    }
    private com.tansun.rule.model.toolbean.Fact generateFact(SingleTblIndexItem item, String type) {
    	String name = item.getClassName()+"."+item.getNameEN();
    	String funcName = funcParamMap.get(name);
    	String vals = item.getControlValue();
    	if (type.equals("when")) {
    		if(item.getControlValue().equals("其他")) {
    			return new com.tansun.rule.model.toolbean.BlankFact();
   			
    		}else {
	    		if (item.getDataType().equals("String")) {
	    			if (!StringUtils.isEmpty(item.getDomain()) && item.getControlValue().indexOf("[") >= 0) {
	    				vals = item.getControlValue().substring(1, item.getControlValue().length() - 1);
	    				return new StringFact(name,funcName,vals.replaceAll("\"", "").split(","),true);
	    			} else {
	    			    //决策表string类型新增!= 20200101 ljt
                        String lowerOpt = "==";
                        if(StringUtils.isNotBlank(item.getLowerOpt())){//excle默认 ==
                        	 lowerOpt = item.getLowerOpt();
                        }
                        return new StringFact(name,funcName,lowerOpt, item.getControlValue());
	    			}
	    		} else if (item.getDataType().equals("Boolean")) {
	    			return new BooleanFact(name,funcName, "==", item.getControlValue().equals("1") ? "true" : "false");
	    		} else {
	    			String lowerOpt = item.getLowerOpt();
	    			if(lowerOpt.equals("[")) lowerOpt = ">=";
	    			if(lowerOpt.equals("(")) lowerOpt = ">";
	    			String upperOpt = item.getUpperOpt().equals("]")? "<=":"<";
	    			String[] valArr = vals.split(",");
	    			if (valArr.length==0){
	    				return new com.tansun.rule.model.toolbean.BlankFact();
	    			}
	    			if(item.getDataType().equals("Date")) {
        				String dateStr1='"'+valArr[1]+'"';
        				String dateStr2='"'+valArr[0]+'"';
        				return new NumericFact(name,funcName,valArr.length>1?dateStr1:null, upperOpt, dateStr2, lowerOpt);
        			}else {
        				return new NumericFact(name,funcName, valArr.length>1?valArr[1]:null, upperOpt, valArr[0], lowerOpt);
        			}	    			
	    			//return new NumericFact(name, valArr.length>1?valArr[1]:null, upperOpt, valArr[0], lowerOpt);
	    			
	    			
	    		}
    		}
    	} else{
    		/*if ("List".equals(item.getCollection())) {
    			retStr = "ruleHelper.insertValue";
    		}*/
    		String val = item.getControlValue();
    		if("true".equals(item.getIsDerives())){
    			val = new FormulaFact(val).toString();
    			NumericFact ret = new NumericFact(name, val);
    			ret.setCollection(item.getCollection());
    			return ret;
    		}else{
    			StringFact ret = new StringFact(name, val);
    			ret.setCollection(item.getCollection());
    			return ret;
    		}
    	}
    }

    private RuleItem getCustomRule(String ruleName, int priority, String factStr, String actionStr) {
        RuleItem rule = new RuleItem();
        rule.setEnabled("on");
        rule.setRuleName(ruleName);
        rule.setSalience(priority);
        DWhen dWhen = new DWhen();
        Fact fact = new Fact();
        fact.setContent(factStr);
        dWhen.setFirstFact(fact);
        DThen dThen = new DThen();
        Action action = new Action();
        action.setContent(actionStr);
        dThen.getListAction().add(action);
        rule.setdWhen(dWhen);
        rule.setdThen(dThen);
        return rule;
    }

    @Override
    public List<SingleTblIndexRow> findTblIndexRowList(String indexId, String version) throws BizException {
        RuleDecisiontableDetail decisiontableDetail = new RuleDecisiontableDetail();
        decisiontableDetail.setManageId(indexId);
        decisiontableDetail.setVersion(version);
        List<RuleDecisiontableDetail> list = this.dao.findList(decisiontableDetail);
        if (list == null) return null;

        List<SingleTblIndexRow> resultList = new ArrayList();
        SingleTblIndexRow indexItem = null;
        SingleTblIndexItem childItem = null;
        int iCol = 0;
        for (RuleDecisiontableDetail tableDetail : list) { //按照row,col 排序列表
            iCol = tableDetail.getColumnNo();
            if (iCol == 0) { //0 列
                indexItem = new SingleTblIndexRow();
                indexItem.setSingleTblRow(new ArrayList<SingleTblIndexItem>());
                childItem = new SingleTblIndexItem();
                try {
                    BeanUtils.copyProperties(childItem, tableDetail);
                    childItem.setNameCN(tableDetail.getNamecn());
                    childItem.setNameEN(tableDetail.getNameen());
                } catch (Exception e) {
                    throw new BizException(e, "E-000000");

                }
                indexItem.getSingleTblRow().add(childItem);
                resultList.add(indexItem);
            } else {
                childItem = new SingleTblIndexItem();
                try {
                    BeanUtils.copyProperties(childItem, tableDetail);
                    childItem.setNameCN(tableDetail.getNamecn());
                    childItem.setNameEN(tableDetail.getNameen());
                } catch (Exception e) {
                    throw new BizException(e, "E-000000");

                }
                if (indexItem.getSingleTblRow() != null)
                    indexItem.getSingleTblRow().add(childItem);
            }
        }
        return resultList;
    }
    
	@Override
	public void clearVersion(RuleManage ruleManage,List<String> versions) {
		if(versions!=null&&versions.size()>0) {
			Map<String,Object> map = new HashMap<String,Object>();
			map.put("projectCode", ruleManage.getProjectCode());
			map.put("manageId", ruleManage.getId());
			map.put("versions", versions);
			this.dao.deleteByMutilVersion(map);
		}
	}
	@Override
	public void updateSetParam(String manageId, RuleSetParamInfo newSetParamInfo, RuleSetParamInfo oldSetParamInfo, boolean setFlag) throws Exception {
           RuleManage  ruleManage =  this.ruleManageService.get(manageId);
           
           RuleDecisiontableDetail decisiontableDetail = new RuleDecisiontableDetail();
           decisiontableDetail.setManageId(manageId);
           decisiontableDetail.setVersion(ruleManage.getActiveVersion());
           List<RuleDecisiontableDetail> list = this.dao.findList(decisiontableDetail);
           if (list == null || list.size() == 0) return ;
           boolean  flag  = false;
           for (RuleDecisiontableDetail desDetail: list  ){
  			 if (setFlag) {
  				 if (desDetail.getClassName().equals(oldSetParamInfo.getCode())) {
  					desDetail.setClassName(newSetParamInfo.getCode());
  					flag =true;
  					this.dao.update(desDetail);
  		
  				 }
  				
			 }else {
				 if (desDetail.getNameen().equals(oldSetParamInfo.getCode())) {
					 desDetail.setNameen(newSetParamInfo.getCode());
					 desDetail.setNamecn(newSetParamInfo.getName()); 
					 flag =true;
					 this.dao.update(desDetail);

				 }

			 }
  			
           }
           if (!flag) return ;
           List<SingleTblIndexRow> resultList = new ArrayList<>();
           SingleTblIndexRow indexItem = null;
           SingleTblIndexItem childItem = null;
           int iCol = 0;
           for (RuleDecisiontableDetail tableDetail : list) { //按照row,col 排序列表
               iCol = tableDetail.getColumnNo();
               if (iCol == 0) { //0 列
                   indexItem = new SingleTblIndexRow();
                   indexItem.setSingleTblRow(new ArrayList<SingleTblIndexItem>());
                   childItem = new SingleTblIndexItem();
                   try {
                       BeanUtils.copyProperties(childItem, tableDetail);
                       childItem.setNameCN(tableDetail.getNamecn());
                       childItem.setNameEN(tableDetail.getNameen());
                   } catch (Exception e) {
                       throw new BizException(e, "E-000000");

                   }
                   indexItem.getSingleTblRow().add(childItem);
                   resultList.add(indexItem);
               } else {
                   childItem = new SingleTblIndexItem();
                   try {
                       BeanUtils.copyProperties(childItem, tableDetail);
                       childItem.setNameCN(tableDetail.getNamecn());
                       childItem.setNameEN(tableDetail.getNameen());
                   } catch (Exception e) {
                       throw new BizException(e, "E-000000");

                   }
                   if (indexItem.getSingleTblRow() != null)
                       indexItem.getSingleTblRow().add(childItem);
               }
           }
           String context = generateRuleFuncMode(ruleManage, resultList);
   		   RuleVersioninfo  versInfo  = new RuleVersioninfo();
	   	   versInfo.setManageId(ruleManage.getId());
	   	   versInfo.setVersion(ruleManage.getActiveVersion());
	   	   List<RuleVersioninfo> vList =	this.ruleVersioninfoService.findList(versInfo);
	   	   if (vList != null && vList.size()>0) {
	   	    	RuleVersioninfo  ruleVer = vList.get(0);
	   	    	ruleVer.setRuleContent(context);
	   	    	this.ruleVersioninfoService.save(ruleVer);
	   	    }
         
	}
	
	
}
